/*
* Copyright (c) 2016 . All Rights Reserved.
*/
package com.cgmnx.admin.biz.rbac.impl;

import com.cgmnx.admin.biz.rbac.RoleBiz;
import com.cgmnx.admin.common.bean.Limiter;
import com.cgmnx.admin.common.bean.Template;
import com.cgmnx.admin.common.enums.ValidEnumType;
import com.cgmnx.admin.common.exception.Preconditions;
import com.cgmnx.admin.dao.entity.rbac.ResourceEntity;
import com.cgmnx.admin.dao.entity.rbac.RoleEntity;
import com.cgmnx.admin.model.enums.rbac.OperationType;
import com.cgmnx.admin.service.aop.Loggable;
import com.cgmnx.admin.service.rbac.ResourceService;
import com.cgmnx.admin.service.rbac.RoleResourceRelationService;
import com.cgmnx.admin.service.rbac.RoleService;
import com.cgmnx.admin.service.rbac.RoleUserRelationService;
import com.cgmnx.admin.service.rbac.UserService;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * @author: created  Date: 16/12/13 Time: 下午7:41
 * @version: 1.0
 */
@Slf4j
@Service
public class RoleBizImpl implements RoleBiz {

    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private RoleUserRelationService roleUserRelationService;

    @Autowired
    private RoleResourceRelationService roleResourceRelationService;

    @Override
    @Loggable(description = "保存角色信息", type = OperationType.ROLE)
    public Integer save(final RoleEntity roleEntity) {

        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleEntity, "角色信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {
                return roleService.save(roleEntity);
            }
        }.execute();


    }

    @Override
    @Loggable(description = "更新角色信息", type = OperationType.ROLE)
    public Integer update(final RoleEntity roleEntity) {

        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleEntity, "角色信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {
                return roleService.update(roleEntity);
            }
        }.execute();

    }

    @Override
    @Loggable(description = "更新角色为有效状态", type = OperationType.ROLE)
    public Void updateValidStatus(List<Integer> idList) {
        return updateStatus(idList, ValidEnumType.VALID);
    }

    @Override
    @Loggable(description = "更新角色为无效状态", type = OperationType.ROLE)
    public Void updateInValidStatus(List<Integer> idList) {
        return updateStatus(idList, ValidEnumType.INVALID);
    }


    private Void updateStatus(final List<Integer> idList, final ValidEnumType type) {
        return new Template<Void>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(idList), "角色id不能为空");
                Preconditions.checkNotNull(type, "角色的有效类型不能为空");
            }

            @Override
            protected Void exec() throws Exception {
                roleService.updateStatus(idList, type);
                return null;
            }
        }.execute();
    }

    @Override
    @Transactional
    @Loggable(description = "给角色分配权限", type = OperationType.ROLE)
    public Void allocationResource(final Integer roleId, final List<Integer> resourceIdList, final String userId) {
        return new Template<Void>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleId, "角色id不能为空");
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(resourceIdList), "分配的资源列表不能为空");
            }

            @Override
            protected Void exec() throws Exception {

                roleResourceRelationService.deleteByRoleId(roleId);

                List<ResourceEntity> resourceEntities = resourceService.queryList(resourceIdList);

                Set<Integer> integers = Sets.newHashSet();

                for (ResourceEntity resourceEntity : resourceEntities) {
                    integers.add(resourceEntity.getId());
                    integers.add(resourceEntity.getParentId());
                }

                log.info("重新分配权限,角色ID:{},资源列表:{}", roleId, integers);
                roleResourceRelationService.allocation(roleId, integers, userId);

                return null;
            }

        }.execute();
    }

    @Override
    public Integer count(final String searchName) {
        return new Template<Integer>() {
            @Override
            protected void check() {
            }

            @Override
            protected Integer exec() throws Exception {
                return roleService.count(searchName, ValidEnumType.VALID);
            }

        }.execute();
    }

    @Override
    public List<RoleEntity> queryPage(final String searchName, final Limiter limiter) {
        return new Template<List<RoleEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(limiter, "分页信息不能为空");
            }

            @Override
            protected List<RoleEntity> exec() throws Exception {
                return roleService.queryPage(searchName, ValidEnumType.VALID, limiter);
            }

        }.execute();
    }

    @Override
    public RoleEntity query(final Integer roleId) {
        return new Template<RoleEntity>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleId, "角色ID不能为空");
            }

            @Override
            protected RoleEntity exec() throws Exception {
                return roleService.queryById(roleId);
            }

        }.execute();
    }

    @Override
    public List<RoleEntity> queryAll() {
        return new Template<List<RoleEntity>>() {
            @Override
            protected void check() {

            }

            @Override
            protected List<RoleEntity> exec() throws Exception {
                return roleService.queryAll();
            }

        }.execute();
    }

    @Override
    public List<RoleEntity> queryByUserIdList(final List<String> userIdList) {
        return new Template<List<RoleEntity>>() {
            @Override
            protected void check() {

            }

            @Override
            protected List<RoleEntity> exec() throws Exception {
                return roleService.queryByUserIdList(userIdList, ValidEnumType.VALID);
            }

        }.execute();

    }

    @Override
    public Integer countRelationUser(final Integer id) {
        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(id, "角色ID不能为空");
            }

            @Override
            protected Integer exec() throws Exception {
                return roleUserRelationService.count(id);
            }

        }.execute();
    }

    @Override
    public List<RoleEntity> queryRelationUserPage(final Integer id, final Limiter limiter) {
        return new Template<List<RoleEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(id, "角色ID不能为空");
                Preconditions.checkNotNull(limiter, "分页信息不能为空");
            }

            @Override
            protected List<RoleEntity> exec() throws Exception {
                return roleUserRelationService.queryPage(id, limiter);
            }

        }.execute();
    }

    @Override
    @Transactional
    @Loggable(description = "给角色解绑用户", type = OperationType.ROLE)
    public Void bindingUser(final Integer roleId, final List<String> userIds, final String currentserId) {
        return new Template<Void>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleId, "角色id不能为空");
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(userIds), "分配的用户列表不能为空");
            }

            @Override
            protected Void exec() throws Exception {

                roleUserRelationService.deleteByUserIdListAndRoleId(roleId, userIds);

                return null;
            }

        }.execute();
    }
}